﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace VkClientIM
{
	public class DraggableBehavior : DependencyObject
	{
		private static bool _isDragging;
		private static Point _offset;

		public static readonly DependencyProperty CanDragProperty =
			DependencyProperty.RegisterAttached("CanDrag",
			typeof(bool),
			typeof(DraggableBehavior),
			new UIPropertyMetadata(false, OnChangeCanDragProperty));

		public static void SetCanDrag(UIElement element, bool o)
		{
			element.SetValue(CanDragProperty, o);
		}

		public static bool GetCanDrag(UIElement element)
		{
			return (bool)element.GetValue(CanDragProperty);
		}

		private static void OnChangeCanDragProperty(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			UIElement element = d as UIElement;
			if (element == null) return;

			if (e.NewValue != e.OldValue)
			{
				if ((bool)e.NewValue)
				{
					element.PreviewMouseDown += ElementPreviewMouseDown;
				//	element.MouseLeave += ElementMouseLeave;
					element.PreviewMouseUp += ElementPreviewMouseUp;
					element.PreviewMouseMove += ElementPreviewMouseMove;
				}
				else
				{
					element.PreviewMouseDown -= ElementPreviewMouseDown;
				//	element.MouseLeave -= ElementMouseLeave;
					element.PreviewMouseUp -= ElementPreviewMouseUp;
					element.PreviewMouseMove -= ElementPreviewMouseMove;
				}
			}
		}

		static void ElementMouseLeave(object sender, MouseEventArgs e)
		{
			_isDragging = false;
		}



		static void ElementPreviewMouseDown(object sender, MouseButtonEventArgs e)
		{
			FrameworkElement element = sender as FrameworkElement;
			FrameworkElement parent = element.Parent as FrameworkElement;
			while ((parent != null) && (!(parent is Canvas)))
			{
				element = parent;
				parent = parent.Parent as FrameworkElement;
			}
			if (parent == null) return;

			_isDragging = true;
			_offset = e.GetPosition(element);
			if( !(e.Source is ButtonBase))
			{
				Mouse.Capture( sender as FrameworkElement, CaptureMode.SubTree );
			}
		}

		private static void ElementPreviewMouseMove(object sender, MouseEventArgs e)
		{
			if (!_isDragging) return;
			FrameworkElement element = sender as FrameworkElement;
			if (element == null) return;
			FrameworkElement parent = element.Parent as FrameworkElement;
			while ((parent!=null)&&(!(parent is Canvas)))
			{
				element = parent;
				parent = parent.Parent as FrameworkElement;
			}
			if (parent==null)
			{
				return;
			}
			Canvas canvas = ( Canvas ) parent;
			Point mousePoint = e.GetPosition(canvas);
			mousePoint.Offset(-_offset.X, -_offset.Y);

			double x = mousePoint.X;
			double y = mousePoint.Y;
			x = ( x < 6 ) ? 6 : x;
			y = ( y < 6 ) ? 6 : y;
			x = (x > (canvas.ActualWidth - element.Width - 6)) ? (canvas.ActualWidth - element.Width - 6) : x;
			y = (y > (canvas.ActualHeight - element.Height - 6)) ? (canvas.ActualHeight - element.Height - 6) : y;
			element.SetValue(Canvas.LeftProperty, x);
			element.SetValue(Canvas.TopProperty, y);
		}

		private static void ElementPreviewMouseUp(object sender,
				MouseButtonEventArgs e)
		{
			_isDragging = false;
			if (!(e.Source is ButtonBase))
			{
				Mouse.Capture( null );
			}
		}

	}


	public class NotDraggableBehavior
		:DependencyObject
	{
		
	}
}
